from django.shortcuts import render
from django.views.decorators.http import require_http_methods

# Create your views here.

"""
1.判断用户名是否重复的功能。
前端(了解)：  当用户输入用户名之后，失去焦点， 发送一个axios(ajax)请求
后端（思路）：
    请求:    接收用户名 
    业务逻辑：     
            根据用户名查询数据库，如果查询结果数量等于0，说明没有注册
                    如果查询结果数量等于1，说明有注册
    响应     JSON 
            {code:0,count:0/1,errmsg:ok}

    路由      GET  usernames/<username>/count/        
    步骤：
        1.  接收用户名
        2.  根据用户名查询数据库
        3.  返回响应         
"""

from django.views import View
from apps.users.models import User
from django.http import JsonResponse


class UsernameCheckView(View):
    # 1. 接收用户名
    def get(self, request, username):
        # 2.根据用户名，查询数据库
        count = User.objects.filter(username=username).count()
        # 3.返回响应
        return JsonResponse({'code': 0, 'count': count, 'errmsg': '请检查您的用户名'})


# @require_http_methods(['GET'])
# def UsernameCheckView(request,username):
#     # 2.根据用户名，查询数据库
#     count = User.objects.filter(username=username).count()
#     # 3.返回响应
#     return JsonResponse({'code': 0, 'count': count, 'errormessage': '请检查您的用户名'})


"""
我们不相信前端提交的任何数据！！！！(前端做不做验证，后端都要做验证）
前端：           当用户输入 用户名，密码，确认密码，手机号，是否同意协议之后，会点击注册按钮
                前端会发送axios请求
后端：
    请求：       接收请求（JSON）。获取数据
    业务逻辑：    验证数据。数据入库
    响应：       JSON {'code':0,'errmsg':'ok'}
                响应码 0 表示成功 400表示失败

    路由：       POST    register/

    步骤：

                1. 接收请求（POST------JSON）
                2. 获取数据
                3. 验证数据
                    3.1 用户名，密码，确认密码，手机号，是否同意协议 都要有
                    3.2 用户名满足规则，用户名不能重复
                    3.3 密码满足规则
                    3.4 确认密码和密码要一致
                    3.5 手机号满足规则，手机号也不能重复
                    3.6 需要同意协议
                4. 数据入库
                5. 返回响应
"""

import json
import re
from django.contrib.auth import login


class RegisterView(View):
    def post(self, request):
        # 接收前端返回得json数据
        json_bytes = request.body
        json_str = json_bytes.decode()
        json_dict = json.loads(json_str)

        # 获取前端返回的json数据
        username = json_dict.get('username')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        allow = json_dict.get('allow')
        print(type(password))

        # 验证数据是否符合规则

        # 1.用户名，密码，确认密码，手机号，是否同意协议,是否填写完整
        if not all([username, password, password2, mobile, allow]):
            return JsonResponse({'code': 400, 'errmsg': '请检查您输入得信息是否完整'})

        # 2.用户名满足规则，用户名不能重复

        if not re.match(r'[a-zA-Z0-9_-]{5,20}', username):
            return JsonResponse({'code': 400, 'errmsg': '请输入5-20个字符的用户名且不能为纯数字'})

        # 3.验证密码是否满足规则
        if len(password) < 8 or len(password) > 20:
            return JsonResponse({'code': 400, 'errmsg': '请输入8-20位长度的密码'})

        # 4.确认密码和密码要一致
        if password != password2:
            return JsonResponse({'code': 400, 'errmsg': '确认密码和密码不一致'})

        # 5.手机号满足规则，手机号也不能重复
        if not re.match(r'1[345789]\d{9}', mobile):
            return JsonResponse({'code': 400, 'errmsg': '请输入正确的手机号'})

        # 6.需要同意协议
        if not allow:
            return JsonResponse({'code': 400, 'errmsg': '请仔细阅读协议并同意协议'})

        # 数据入库
        # 问题：数据可以入库，但是密码不能加密
        # User.objects.create(username=username,password=password,mobile=mobile)

        # 调用create_user密码加密
        user = User.objects.create_user(username=username, password=password, mobile=mobile)

        # 如何设置session信息
        # request.session['user_id']=user.id
        # 系统（Django）为我们提供了 状态保持的方法 login

        login(request, user=user)

        # 返回响应
        return JsonResponse({'code': 200, 'errmsg': 'ok!'})


"""
如果需求是注册成功后即表示用户认证通过，那么此时可以在注册成功后实现状态保持 (注册成功即已经登录)  
如果需求是注册成功后不表示用户认证通过，那么此时不用在注册成功后实现状态保持 (注册成功，单独登录)

实现状态保持主要有两种方式：
    在客户端存储信息使用Cookie
    在服务器端存储信息使用Session
"""

"""
登录
前端：
        当用户把用户名和密码输入完成之后，会点击登录按钮。这个时候前端应该发送一个axios请求
后端：
    请求    ：  接收数据，验证数据
    业务逻辑：   验证用户名和密码是否正确，session
    响应    ： 返回JSON数据 0 成功。 400 失败
    POST        /login/
步骤：
    1. 接收数据
    2. 验证数据
    3. 验证用户名和密码是否正确
    4. session
    5. 判断是否记住登录
    6. 返回响应
"""


# 登录
class LoginView(View):
    def post(self, request):
        # 1.接收数据
        data = json.loads(request.body.decode())
        username = data.get('username')
        password = data.get('password')
        remembered = data.get('remembered')

        # 2.验证数据
        if not all([username, password]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        # 3.验证用户名和密码是否正确
        # 我们可以通过模型根据用户名来查询
        # User.objects.get(username=username)

        # USERNAME_FIELD 我们可以根据 修改 User. USERNAME_FIELD 字段
        # 来影响authenticate 的查询
        # authenticate 就是根据 USERNAME_FIELD 来查询

        if re.match(r'1[3-9]\d{9}', username):
            User.USERNAME_FIELD = 'mobile'
        else:
            User.USERNAME_FIELD = 'username'

        # 方式2
        from django.contrib.auth import authenticate
        # authenticate 传递用户名和密码
        # 如果用户名和密码正确，则返回 User信息
        # 如果用户名和密码不正确，则返回 None
        user = authenticate(username=username, password=password)
        if user is None:
            return JsonResponse({'code': '400', 'errmsg': '账户或密码错误'})

        # 4.session
        from django.contrib.auth import login
        login(request, user)

        # 5.判断是否记住登录
        if remembered is not None:
            # 记住登录
            request.session.set_expiry(None)
        else:
            # 不记住登录
            request.session.set_expiry(0)

        # 6.返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok'})
